<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Hello Vue</title>

    <script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.7/vue.global.js"></script>
    <link
      href="https://cdn.bootcdn.net/ajax/libs/tailwindcss/2.0.4/tailwind.min.css"
      rel="stylesheet"
    />
    <style>
      [v-cloak] {
        display: none;
      }
    </style>
  </head>
  <body>
    <div id="app" class="w-80 mx-auto">
      <h1 v-cloak class="mt-20 text-green-500 text-4xl text-center">{{msg}}</h1>
      <component-demo></component-demo>
      <directives></directives>
      <event-handling></event-handling>
      <event-bubble></event-bubble>
      <keyboard-form></keyboard-form>
      <style-bandings></style-bandings>
    </div>

    <script>
      const { createApp, defineComponent } = Vue

      // 这是一个示例组件
      const ComponentDemo = defineComponent({
        data: () => ({
          desc: 'This is a component.',
        }),
        template: `<p class="mt-6  text-gray-500 text-center italic"> {{desc}}</p>`,
      })

      // 指令
      const Directives = defineComponent({
        data: () => ({
          ele: '<b>v-html 这是 b 标签 </b>',
          text: 'v-text 这是一段文本',
          title: '动态绑定 title 的值',
        }),
        template: `
        <div class="mt-6 flex flex-col column items-center  divide-y divide-green-400">
          <p class="p-1" v-html="ele"></p>  
          <p class="p-1" v-text="text"></p>
          <p class="p-1" v-cloak>v-cloak 测试</p>
          <a class="p-1 text-blue-500" href="#" :title="title">Hover me.</a>
        </div>`,
      })

      // 事件处理
      const EventHandling = defineComponent({
        data: () => ({
          counter: 0,
        }),
        methods: {
          handleClick() {
            alert('🚩Click !')
          },
          handleMouseleave() {
            this.counter += 1
          },
        },
        template: `
        <div class="flex flex-col justify-around mt-8">
          <p class="mb-4 text-center">
            鼠标移出次数：
            <span class="text-green-500 text-2xl"> {{counter}}</span>
          </p>
          <button 
            @click="handleClick" 
            class="mb-4 bg-gray-100 px-4 py-2  rounded shadow-md"
          >点击这里</button>
          <button 
            @mouseleave="handleMouseleave" 
            class="mb-4 bg-gray-100 px-4 py-2  rounded shadow-md"
          >鼠标移入再移出</button>
        </div>`,
      })

      // 事件冒泡
      const EventBubble = defineComponent({
        data: () => ({}),
        methods: {
          clickContainer() {
            alert('点击容器')
          },
          clickInner() {
            alert('点击内部')
          },
          defaultEvent() {
            alert('阻止默认事件')
          },
        },
        template: `
          <div 
            @click="clickContainer" 
            class="flex flex-col justify-center items-center rounded text-transparent mx-auto w-auto p-9 bg-gray-100 cursor-pointer shadow-md"
          >
            <div 
              @click.stop="clickInner" 
              class="w-full h-32 bg-green-300 border-green-600 border-2  text-white  font-bold  flex  justify-center items-center shadow-md"
            >阻止冒泡</div>  
            <a 
              @click.prevent="defaultEvent" 
              href="#" 
              class="w-full  mt-6 p-2 text-xs  bg-green-300 border-green-600 border-2  text-white font-bold  shadow-md"
            >这是a标签，阻止默认事件，点击不会跳转</a>
          </div>
        `,
      })

      // 表单及键盘事件
      const KeyboardForm = defineComponent({
        data: () => ({
          inputValue: '🤦‍♂️Tom',
        }),
        methods: {
          textInputFocus() {
            console.log('文本输入框 focus')
          },
          handleKeydown(e) {
            console.log(e.keyCode)
          },
          changeInputValue() {
            console.log(1231)

            this.inputValue = this.inputValue === '🤦‍♀️Lucy' ? '🤦‍♂️Tom' : '🤦‍♀️Lucy'
          },
        },
        template: `
          <div class="flex flex-col justify-center items-center  my-4 p-8  bg-gray-100 rounded shadow-md">
            <input 
              class="p-2 w-full text-sm mb-4 border-gray-400 border-2"
              type="text" 
              placeholder="focus" 
              @focus="textInputFocus"
            />  
            <input 
              class="p-2 w-full text-sm mb-4 border-gray-400 border-2"
              type="text" 
              placeholder="键盘事件" 
              @keydown="handleKeydown"
            />  
            <input 
              class="p-2 w-full text-sm mb-4 border-gray-400 border-2"
              type="text" 
              placeholder="focus" 
              :value="inputValue"
            />  
            <button 
              @click="changeInputValue" 
              class="mb-4 w-full text-white bg-green-400 px-4 py-2  rounded shadow-md"
            >改变输入框的 value</button>
          </div>
        `,
      })

      // 样式绑定
      const StyleBandings = defineComponent({
        data: () => ({
          style: 'color: blue',
          singleClass: 'text-red-500', //  .text-red-500 in tailwind css
          multipleClass: ['px-2 py-1 bg-green-500 text-white text-sm rounded'],
        }),
        template: `
          <div class="flex flex-col justify-center items-center  my-4 p-8  bg-gray-100 rounded shadow-md">
            <p :style="style">绑定 style</p>
            <p :class="singleClass">绑定单个 class</p>
            <p :class="multipleClass">绑定多个 class</p>
          </div>
        `,
      })

      // 根组件
      const App = defineComponent({
        components: {
          'component-demo': ComponentDemo,
          directives: Directives,
          'event-handling': EventHandling,
          'event-bubble': EventBubble,
          'keyboard-form': KeyboardForm,
          'style-bandings': StyleBandings,
        },
        data: () => ({
          msg: '🎉 Hello Vue !',
        }),
        mounted() {
          console.log('App mounted!')
        },
      })

      createApp(App).mount('#app')
    </script>
  </body>
</html>
